package com.enation.app.javashop.seller.api.passport;

import com.dag.eagleshop.core.delivery.model.dto.JsonBean;
import com.enation.app.javashop.core.base.SceneType;
import com.enation.app.javashop.core.client.member.ShopClient;
import com.enation.app.javashop.core.client.system.CaptchaClient;
import com.enation.app.javashop.core.client.system.SmsClient;
import com.enation.app.javashop.core.member.MemberErrorCode;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.vo.MemberVO;
import com.enation.app.javashop.core.member.model.vo.SellerInfoVO;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.member.service.MemberSecurityManager;
import com.enation.app.javashop.core.passport.dto.AppLoginDTO;
import com.enation.app.javashop.core.passport.dto.SmsSendDTO;
import com.enation.app.javashop.core.passport.service.AliyunUtilsManager;
import com.enation.app.javashop.core.passport.service.PassportManager;
import com.enation.app.javashop.core.shop.model.dos.Clerk;
import com.enation.app.javashop.core.shop.model.enums.ShopStatusEnum;
import com.enation.app.javashop.core.shop.model.vo.ShopVO;
import com.enation.app.javashop.core.shop.model.vo.SubmitApplyVO;
import com.enation.app.javashop.core.shop.service.ClerkManager;
import com.enation.app.javashop.core.shop.service.ShopManager;
import com.enation.app.javashop.core.system.SystemErrorCode;
import com.enation.app.javashop.framework.JavashopConfig;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Buyer;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.BeanUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.HashMap;
import java.util.Map;


/**
 * 会员登录注册API
 *
 * @author zh
 * @version v7.0
 * @since v7.0
 * 2018年3月23日 上午10:12:12
 */
@RestController
@RequestMapping("/seller/login")
@Api(description = "商家登录API")
@Validated
public class PassportLoginSellerController {

    @Autowired
    private PassportManager passportManager;
    @Autowired
    private CaptchaClient captchaClient;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private ClerkManager clerkManager;
    @Autowired
    private SmsClient smsClient;
    @Autowired
    private JavashopConfig javashopConfig;
    @Autowired
    private ShopClient shopClient;
    @Autowired
    private ShopManager shopManager;
    @Autowired
    private AliyunUtilsManager aliyunUtilsManager;

    @Autowired
    private MemberSecurityManager memberSecurityManager;

    /**
     * PC端登录
     * @param username
     * @param password
     * @param captcha
     * @param uuid
     * @return
     */
    @GetMapping()
    @ApiOperation(value = "用户名（手机号）/密码登录API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "captcha", value = "验证码", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "uuid", value = "客户端唯一标识", required = true, dataType = "String", paramType = "query"),
    })
    public MemberVO login(@NotEmpty(message = "用户名不能为空") String username, @NotEmpty(message = "密码不能为空") String password, String captcha, @NotEmpty(message = "uuid不能为空") String uuid) {
        //验证图片验证码是否正确
        if(!StringUtils.isEmpty(captcha)){
            boolean isPass = captchaClient.valid(uuid, captcha, SceneType.LOGIN.name());
            if (!isPass) {
                throw new ServiceException(MemberErrorCode.E107.code(), "图片验证码错误");
            }
        }
        SellerInfoVO sellerInfoVO = new SellerInfoVO();
        //返回会员信息
        MemberVO memberVO = memberManager.login(username, password, 2);
        //查询店员
        BeanUtil.copyProperties(memberVO, sellerInfoVO);
        Clerk clerk = clerkManager.getClerkByMemberId(memberVO.getUid());
        if (clerk != null) {
            sellerInfoVO.setRoleId(clerk.getRoleId());
            sellerInfoVO.setFounder(clerk.getFounder());
            return sellerInfoVO;
        }
        return memberVO;

    }

    /**
     * 通过阿里云滑动验证发送短信验证码
     * @param smsSendDTO
     * @return
     */
    @PostMapping(value = "/smscode")
    @ApiOperation(value = "APP发送登录验证码")
    public Map sendSmsCode(@Valid @RequestBody SmsSendDTO smsSendDTO) {
        // 阿里云滑动验证
        // Boolean checkRes = aliyunUtilsManager.check(smsSendDTO.getSessionId(), smsSendDTO.getNcToken(), smsSendDTO.getSig());
        // if(!checkRes){
        //     throw  new ServiceException(SystemErrorCode.E928.code(),"验签失败");
        // }

        // 登录短信验证码
        passportManager.sendLoginSmsCode(smsSendDTO.getMobile());
        // 返回端信息验证有效时间(分钟   ）
        String timeout = javashopConfig.getSmscodeTimout() / 60 + "";
        Map<String, String> params = Maps.newHashMap();
        params.put("timeout",timeout);
        return params;
    }

    /**
     * APP商户端登陆 并自动注册
     * 无密码登录和注册 每次登录都需要输入验证码(短信验证码登录和密码登录)
     * @return
     */
    @PostMapping("/app")
    @ApiOperation(value = "商户端APP码登录API （动态短信和用户名密码登录）")
    public SellerInfoVO mobileLogin(@RequestBody AppLoginDTO appLoginDTO) {
        MemberVO memberVO =null;
        if(appLoginDTO.getLoginType()==0){
            String mobile = appLoginDTO.getMobile();
            // 手机验证码校验
            boolean isPass = smsClient.valid(SceneType.LOGIN.name(), appLoginDTO.getMobile(),  appLoginDTO.getSmsCode());
            if (!isPass) {
                throw new ServiceException(MemberErrorCode.E107.code(), "短信验证码错误");
            }
            // 登陆
            memberVO = memberManager.mobileLogin(mobile, 2);
        }else{
            //返回会员信息
            memberVO = memberManager.login(appLoginDTO.getUserName(), appLoginDTO.getPassword(), 2);
        }

        return buildSeller(memberVO);
    }

    @GetMapping("/getMember")
    @ApiOperation(value = "ios获取用户详情")
    public SellerInfoVO getMember() {
        MemberVO memberVO = memberManager.getMember();
        if (memberVO == null) {
            return new SellerInfoVO();
        }

        return buildSeller(memberVO);
    }


    /**
     * 商户APP 店铺注册  店铺状态必须处于 【 APPLYING 申请中】
     * @param submitApplyVO
     * @return
     */
    @ApiOperation(value = "会员申请店铺")
    @PostMapping("/apply")
    public Map submitApply(@RequestBody SubmitApplyVO submitApplyVO) {
        // 通过买家身份进行商户申请开店
        Buyer buyer = UserContext.getBuyer();
        if(buyer==null){
            throw new ServiceException("500","尚未注册会员");
        }

        // 店铺是否已经初始化
        ShopVO shopVO = shopManager.getShopByMemberId(buyer.getUid());
        if(shopVO==null){
            shopManager.saveInit();
        }

        // 地址处理  省市区映射到本地地址库region Id
        // TODO

        // 更新店铺注册信息
        boolean state =shopManager.submitApply(submitApplyVO);
        //给前端返回shop_id，用于推送的别名
        Map map=new HashMap();
        map.put("state",state);
        ShopVO shop = shopClient.getShopByMemberId(buyer.getUid());
        if(shop==null ||shop.getShopDisable()==null){
            map.put("sellerId",null);
        }else{
            map.put("sellerId",shop.getShopId());
        }
        return map;
    }

    @PostMapping("/changePassword")
    @ApiOperation(value = "忘记密码 修改密码")
    public void changePassword(@RequestBody AppLoginDTO appLoginDTO) {
        // 手机验证码校验
        boolean isPass = smsClient.valid(SceneType.VALIDATE_MOBILE.name(), appLoginDTO.getMobile(),  appLoginDTO.getSmsCode());
        if(!isPass){
            throw new ServiceException(MemberErrorCode.E107.code(), "短信验证码不正确");
        }
        Member memberByMobile = this.memberManager.getMemberByMobile(appLoginDTO.getMobile());
        this.memberSecurityManager.updatePassword(memberByMobile.getMemberId(), appLoginDTO.getPassword());
    }

    @GetMapping("/checkPassword")
    @ApiOperation(value = "校验商户登录密码")
    public JsonBean checkPassword(@NotBlank(message = "登录密码不能为空") String password) {
        Seller seller = UserContext.getSeller();
        if (ObjectUtils.isEmpty(seller)) {
            throw new ServiceException(MemberErrorCode.E110.code(), "会员已经退出！");
        }
        memberManager.validation(seller.getUsername(), password);
        return new JsonBean("验证成功");
    }

    private SellerInfoVO buildSeller(MemberVO memberVO){
        SellerInfoVO sellerInfoVO = new SellerInfoVO();

        BeanUtil.copyProperties(memberVO, sellerInfoVO);

        ShopVO shop = shopClient.getShopByMemberId(memberVO.getUid());
        //【UN_APPLY 未申请 ---申请页面】   【OPEN 营业中 ---商户首页】   【APPLY 待审核、CLOSED 已关闭 ---- 商户提示页面】   【 APPLYING 申请中、REFUSED 已拒绝（已改成APPYING）--- 商户注册页面】
        if(shop==null ||shop.getShopDisable()==null){
            sellerInfoVO.setShopStatus(ShopStatusEnum.UN_APPLY.name());
            sellerInfoVO.setSellerId(null);
        }else{
            sellerInfoVO.setSellerId(shop.getShopId());
            sellerInfoVO.setShopName(shop.getShopName());
            sellerInfoVO.setShopLogo(shop.getShopLogo());
            sellerInfoVO.setShopStatus(shop.getShopDisable());
            sellerInfoVO.checkStatusReason();
        }
        // 店员信息
        Clerk clerk = clerkManager.getClerkByMemberId(memberVO.getUid());
        if (clerk != null) {
            sellerInfoVO.setRoleId(clerk.getRoleId());
            sellerInfoVO.setFounder(clerk.getFounder());
        }
        return sellerInfoVO;
    }


}
